package com.zhala.system.service.impl;

import com.github.pagehelper.PageInfo;
import com.zhala.common.core.domain.CommonResult;
import com.zhala.common.core.domain.PageResult;
import com.zhala.common.exception.ServiceException;
import com.zhala.common.utils.DateUtils;
import com.zhala.common.utils.StringUtils;
import com.zhala.common.utils.uuid.IdUtils;
import com.zhala.system.config.MaterialConfig;
import com.zhala.system.config.MaterialItem;
import com.zhala.system.domain.ZlSteelBigPipe;
import com.zhala.system.domain.ZlSteelPipe;
import com.zhala.system.domain.ZlSteelPlate;
import com.zhala.system.domain.vo.*;
import com.zhala.system.mapper.ZlSteelBigPipeMapper;
import com.zhala.system.mapper.ZlSteelPipeMapper;
import com.zhala.system.mapper.ZlSteelPlateMapper;
import com.zhala.system.service.CommonService;
import com.zhala.system.service.IZlSteelPipeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static com.zhala.common.utils.PageUtils.startPage;

/**
 * 管节Service业务层处理
 *
 * @author ruoyi
 * @date 2024-11-11
 */
@Service

public class ZlSteelPipeServiceImpl implements IZlSteelPipeService {
    @Autowired
    private ZlSteelPipeMapper zlSteelPipeMapper;
    @Autowired
    private ZlSteelBigPipeMapper zlSteelBigPipeMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private ZlSteelPlateMapper zlSteelPlateMapper;
    @Autowired
    private MaterialConfig config;

    /**
     * 查询管节
     *
     * @param CREATOR 管节主键
     * @return 管节
     */
    @Override
    public ZlSteelPipe selectZlSteelPipeByCREATOR(String CREATOR) {
        return zlSteelPipeMapper.selectZlSteelPipeByCREATOR(CREATOR);
    }

    /**
     * 查询管节列表
     *
     * @param zlSteelPipe 管节
     * @return 管节
     */
    @Override
    public List<ZlSteelPipe> selectZlSteelPipeList(ZlSteelPipe zlSteelPipe) {
        return zlSteelPipeMapper.selectZlSteelPipeList(zlSteelPipe);
    }

    /**
     * 新增管节
     *
     * @param zlSteelPipe 管节
     * @return 结果
     */
    @Override
    public int insertZlSteelPipe(ZlSteelPipe zlSteelPipe) {
        zlSteelPipe.setCreateTime(DateUtils.getNowDate());
        return zlSteelPipeMapper.insertZlSteelPipe(zlSteelPipe);
    }

    /**
     * 修改管节
     *
     * @param zlSteelPipe 管节
     * @return 结果
     */
    @Override
    public int updateZlSteelPipe(ZlSteelPipe zlSteelPipe) {
        zlSteelPipe.setUpdateTime(DateUtils.getNowDate());
        return zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
    }

    /**
     * 批量删除管节
     *
     * @param CREATORs 需要删除的管节主键
     * @return 结果
     */
    @Override
    public int deleteZlSteelPipeByCREATORs(String[] CREATORs) {
        return zlSteelPipeMapper.deleteZlSteelPipeByCREATORs(CREATORs);
    }

    /**
     * 删除管节信息
     *
     * @param CREATOR 管节主键
     * @return 结果
     */
    @Override
    public int deleteZlSteelPipeByCREATOR(String CREATOR) {
        return zlSteelPipeMapper.deleteZlSteelPipeByCREATOR(CREATOR);
    }


    @Override
    @Transactional
    public CommonResult<Boolean> settings(SteelPipeSettingsReqVO reqVO) {
        List<ZlSteelPlate> used = zlSteelPlateMapper.listUsed(reqVO.getSteelPlateIdList());
        if (!CollectionUtils.isEmpty(used)) {
            return CommonResult.error("钢板已经使用[" + used.get(0).getSerialNum() + "]，请刷新列表稍后再试！");
        }
        // 创建一个新的ZlSteelPipe对象
        ZlSteelPipe zlSteelPipe = new ZlSteelPipe();
        // 使用BeanUtils工具类将请求对象的属性值拷贝到ZlSteelPipe对象中
        BeanUtils.copyProperties(reqVO, zlSteelPipe);
        // 为ZlSteelPipe对象设置唯一的标识符
        zlSteelPipe.setId(IdUtils.fastUUID());
        // 设置删除标记为false，表示该记录未被删除
        zlSteelPipe.setDeleted(false);
        zlSteelPipe.setStatus(0);
        zlSteelPipe.setProcedure(2);
        ZlSteelPlate plate = zlSteelPlateMapper.selectZlSteelPlateByID(reqVO.getSteelPlateIdList().get(0));
        if (plate == null) {
            return CommonResult.error("钢板信息不存在,请检查参数是否正确");
        }
        zlSteelPipe.setMaterial(plate.getMaterial());
        // 调用通用服务的初始化方法，设置创建时间、更新时间等公共字段
        commonService.initPojo(zlSteelPipe);
        // 调用Mapper方法将ZlSteelPipe对象插入到数据库中
        zlSteelPipeMapper.insertZlSteelPipe(zlSteelPipe);
        //设置钢板与管子关联
        zlSteelPlateMapper.setPipeId(zlSteelPipe.getId(), reqVO.getSteelPlateIdList());
        // 返回操作成功的结果
        return CommonResult.success(true);
    }

    /**
     * 执行钢管的下料操作
     * 此方法首先根据请求中的ID查询钢管信息，然后更新下料相关字段
     * 接着检查钢板ID列表，如果为空，则返回错误信息
     * 最后，对每个钢板执行下料操作，并返回成功结果
     *
     * @param reqVO 钢管下料请求对象，包含钢管ID和钢板下料信息
     * @return 返回一个通用结果对象，包含操作是否成功的布尔值
     */
    @Override
    @Transactional
    public CommonResult<Boolean> blanking(SteelPipeBlankingReqVO reqVO) {
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        // 更新钢管的下料结束时间和操作者
        zlSteelPipe.setBlankingEndTime(DateUtils.getNowDate());
        zlSteelPipe.setBlankingDealUser(commonService.getUserNickName());
        zlSteelPipe.setProcedure(3);
        zlSteelPipe.setUpdateBy(zlSteelPipe.getBlankingDealUser());
        // 更新数据库中的钢管信息
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
        // 检查钢板ID列表是否为空，如果为空，则返回错误信息
        if (CollectionUtils.isEmpty(reqVO.getSteelPlateIdList())) {
            return CommonResult.error("钢板制备信息不能为空");
        }
        // 遍历钢板ID列表，执行下料操作
        for (SteelPlateBlankingReqVO blankingReqVO : reqVO.getSteelPlateIdList()) {
            // 调用方法执行钢板的下料
            zlSteelPlateMapper.blanking(blankingReqVO.getId(), blankingReqVO.getBlankingTime(), blankingReqVO.getPreparationTime());
        }
        // 返回操作成功结果
        return CommonResult.success(true);
    }

    @Override
    @Transactional
    public CommonResult<Boolean> blankingUpdate(SteelPipeBlankingReqVO reqVO) {
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        // 更新钢管的下料结束时间和操作者
        zlSteelPipe.setBlankingEndTime(DateUtils.getNowDate());
        zlSteelPipe.setBlankingDealUser(commonService.getUserNickName());
        zlSteelPipe.setUpdateBy(zlSteelPipe.getBlankingDealUser());
        // 更新数据库中的钢管信息
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
        // 检查钢板ID列表是否为空，如果为空，则返回错误信息
        if (CollectionUtils.isEmpty(reqVO.getSteelPlateIdList())) {
            return CommonResult.error("钢板制备信息不能为空");
        }
        // 遍历钢板ID列表，执行下料操作
        for (SteelPlateBlankingReqVO blankingReqVO : reqVO.getSteelPlateIdList()) {
            // 调用方法执行钢板的下料
            zlSteelPlateMapper.blanking(blankingReqVO.getId(), blankingReqVO.getBlankingTime(), blankingReqVO.getPreparationTime());
        }
        // 返回操作成功结果
        return CommonResult.success(true);
    }

    /**
     * 处理钢管卷板工序的相关信息
     *
     * @param reqVO 钢管卷板工序请求对象，包含卷板工序所需的信息
     * @return 返回一个CommonResult对象，包含操作结果的布尔值
     */
    @Override
    @Transactional
    public CommonResult<Boolean> coil(SteelPipeCoilReqVO reqVO,Boolean isUpdate) {
        // 验证钢管信息并获取钢管对象
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        // 设置卷板结束时间
        zlSteelPipe.setCoilEndTime(DateUtils.getNowDate());
        // 设置处理卷板工序的用户
        zlSteelPipe.setCoilDealUser(commonService.getUserNickName());
        if(!isUpdate){
            // 设置工序状态为4，表示卷板工序完成
            zlSteelPipe.setProcedure(4);
        }
        // 更新钢管信息
        commonService.updatePojo(zlSteelPipe);
        // 更新数据库中的钢管信息
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
        // 检查钢板ID列表是否为空，如果为空，则返回错误信息
        if (CollectionUtils.isEmpty(reqVO.getSteelPlateIdList())) {
            return CommonResult.error("卷板工序信息不能为空");
        }
        // 遍历钢板ID列表，更新每块钢板的卷板时间
        for (SteelPlateCoilReqVO coil : reqVO.getSteelPlateIdList()) {
            zlSteelPlateMapper.coil(coil.getId(), coil.getCoilStartTime(), coil.getCoilEndTime());
        }
        // 返回操作成功结果
        return CommonResult.success(true);
    }




    /**
     * 执行钢管的圈圆操作
     *
     * @param reqVO 钢管圈圆请求对象，包含圈圆操作的相关信息
     * @return 返回一个通用结果对象，表示圈圆操作是否成功
     */
    @Override
    public CommonResult<Boolean> plateCircle(SteelPipePlateCircleReqVO reqVO) {
        // 验证请求的合法性并获取钢管对象
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        // 设置钢管圈圆结束时间
        zlSteelPipe.setPlateCircleEndTime(reqVO.getPlateCircleEndTime());
        // 设置处理用户信息
        zlSteelPipe.setPlateCircleDealUser(commonService.getUserNickName());
        // 更新工序状态为5，表示已完成圈圆
        zlSteelPipe.setProcedure(5);
        // 更新数据库中的钢管信息
        commonService.updatePojo(zlSteelPipe);
        // 再次更新数据库中的钢管信息，确保信息准确无误地保存
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
        // 返回操作成功结果
        return CommonResult.success(true);
    }


    /**
     * 纵缝焊接操作
     * <p>
     * 此方法负责将焊接相关信息更新到数据库中，包括焊接用户、焊接开始和结束时间等
     * 它首先验证请求的合法性，然后更新钢管的焊接信息，并保存到数据库
     *
     * @param reqVO 包含焊接请求信息的对象
     * @return 返回一个通用结果对象，表示焊接操作是否成功
     */
    @Override
    public CommonResult<Boolean> weld(SteelPipeWeldReqVO reqVO,Boolean isUpdate) {
        // 验证请求的合法性并获取要焊接的钢管对象
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        // 设置焊接用户
        zlSteelPipe.setWeldUser(reqVO.getWeldUser());
        // 设置焊接开始时间
        zlSteelPipe.setWeldStartTime(reqVO.getWeldStartTime());
        // 设置焊接结束时间
        zlSteelPipe.setWeldEndTime(reqVO.getWeldEndTime());
        // 设置焊接处理用户，使用通用服务获取当前用户的昵称
        zlSteelPipe.setWeldDealUser(commonService.getUserNickName());
        if(!isUpdate){
            // 设置工序号为6，表示焊接工序
            zlSteelPipe.setProcedure(6);
        }
        // 使用通用服务更新数据库中的钢管信息
        commonService.updatePojo(zlSteelPipe);
        // 调用Mapper方法更新数据库中的钢管信息
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);

        // 返回操作成功结果
        return CommonResult.success(true);
    }

    @Override
    public CommonResult<Boolean> scrap(PipeScrapReqVO reqVO) {
        // 验证请求的合法性并获取要焊接的钢管对象
        ZlSteelPipe zlSteelPipe = validate(reqVO.getId());
        zlSteelPipe.setStatus(2);
        commonService.updatePojo(zlSteelPipe);
        zlSteelPipeMapper.updateZlSteelPipe(zlSteelPipe);
        return CommonResult.success(true);
    }


    /**
     * 获取管节信息
     * 根据管节ID查询并返回管节的详细信息如果未找到对应的管节，则返回错误信息
     *
     * @param id 管节ID，用于查询特定的管节信息
     * @return CommonResult<SteelPipeRespVO> 包含管节信息的响应对象，或者包含错误信息的响应对象
     */
    @Override
    public CommonResult<SteelPipeRespVO> info(String id, Integer type) {
        // 根据ID查询管节信息
        ZlSteelPipe zlSteelPipe = validate(id);
        // 创建响应对象并复制属性
        SteelPipeRespVO respVO = new SteelPipeRespVO();
        BeanUtils.copyProperties(zlSteelPipe, respVO);
        // 查询并设置与该管节相关的钢板列表
        respVO.setSteelPlateList(zlSteelPlateMapper.listByPipeId(id));
        if (type != null && type == 1) {
            respVO.setTimeLineList(this.buildTimeLine(respVO.getSteelPlateList().get(0), zlSteelPipe));
        }
        // 返回包含管节信息的成功响应
        return CommonResult.success(respVO);
    }

    /**
     * 构建时间线
     * 根据钢板响应对象和直缝钢管对象的信息，构建一系列时间线对象
     * 时间线对象包括了各个生产环节的名称和对应的时间
     *
     * @param plate       钢板响应对象，包含钢板的创建时间等信息
     * @param zlSteelPipe 直缝钢管对象，包含各个生产环节的结束时间等信息
     * @return 返回一个时间线对象列表，每个对象代表一个生产环节及其时间
     */
    private List<TimeLineVO> buildTimeLine(SteelPlateRespVO plate, ZlSteelPipe zlSteelPipe) {
        // 初始化时间线列表
        List<TimeLineVO> list = new ArrayList<>();

        // 如果钢板创建时间不为空，则添加钢板进场检验时间线
        if (plate.getCreateTime() != null) {
            list.add(new TimeLineVO("钢板进场检验", plate.getCreateTime()));
        }
        // 如果直缝钢管的钢板下料结束时间不为空，则添加钢板下料时间线
        if (zlSteelPipe.getBlankingEndTime() != null) {
            list.add(new TimeLineVO("钢板下料", zlSteelPipe.getBlankingEndTime()));
        }
        // 如果直缝钢管的卷板结束时间不为空，则添加卷板时间线
        if (zlSteelPipe.getCoilEndTime() != null) {
            list.add(new TimeLineVO("卷板", zlSteelPipe.getCoilEndTime()));
        }
        // 如果直缝钢管的管节组圆结束时间不为空，则添加管节组圆时间线
        if (zlSteelPipe.getPlateCircleEndTime() != null) {
            list.add(new TimeLineVO("管节组圆", zlSteelPipe.getPlateCircleEndTime()));
        }
        // 如果直缝钢管的纵缝焊接结束时间不为空，则添加纵缝焊接时间线
        // 注意：这里错误地使用了plateCircleEndTime，应该使用zlSteelPipe.getWeldEndTime()
        if (zlSteelPipe.getWeldEndTime() != null) {
            list.add(new TimeLineVO("纵缝焊接", zlSteelPipe.getWeldEndTime()));
        }
        // 如果直缝钢管的状态不为空且为2，则添加报废时间线
        // 这里假设状态为2表示报废
        if (zlSteelPipe.getStatus() != null && zlSteelPipe.getStatus() == 2) {
            list.add(new TimeLineVO("报废", zlSteelPipe.getUpdateTime()));
        }
        // 返回构建好的时间线列表
        return list;
    }

    /**
     * 管节待办或已完成列表
     *
     * @param reqVO 分页查询条件对象，包含页码、页面大小、月份等查询参数
     * @return 返回一个分页结果对象，包含管道信息列表和总记录数
     */
    @Override
    public PageResult<List<PipePageRespVO>> page(PipePageReqVO reqVO) {
        // 初始化分页参数
        startPage(reqVO.getPageNo(), reqVO.getPageSize());

        // 获取月份的开始日期和结束日期，用于查询
        Date monthStartDate = reqVO.getMonth() != null ? DateUtils.getMonthStartDate(reqVO.getMonth()) : null;
        Date monthEndDate = reqVO.getMonth() != null ? DateUtils.getMonthEndDate(reqVO.getMonth()) : null;

        // 调用Mapper方法进行分页查询
        List<PipePageRespVO> list = zlSteelPipeMapper.pageList(monthStartDate, monthEndDate, reqVO.getPipeNum(), reqVO.getSource());

        // 创建分页结果对象
        PageResult result = new PageResult();
        // 设置总记录数
        result.setTotal(new PageInfo(list).getTotal());
        // 设置分页列表
        result.setList(list);

        // 返回分页结果
        return result;
    }


    /**
     * 获取所有大管列表
     *
     * @param reqVO 分页查询条件对象，包含页码、页面大小、月份等查询参数
     * @return 返回一个分页结果对象，包含管道信息列表和总记录数
     */
    @Override
    public PageResult<List<ZlSteelBigPipe>> newPage(PipeNewPageReqVO reqVO) {
        // 初始化分页参数
        startPage(reqVO.getPageNo(), reqVO.getPageSize());
        // 调用Mapper方法进行分页查询
        List<ZlSteelBigPipe> list = zlSteelBigPipeMapper.newPageList(reqVO.getPipeNum());
        // 创建分页结果对象
        PageResult result = new PageResult();
        // 设置总记录数
        result.setTotal(new PageInfo(list).getTotal());
        // 设置分页列表
        result.setList(list);
        // 返回分页结果
        return result;
    }

    /**
     * 获取未使用的钢管列表
     * <p>
     * 该方法通过调用zlSteelPipeMapper中的unUsePipe方法来获取当前未被使用的钢管（ZlSteelPipe）列表
     * 主要用于展示可用的钢管资源，以便进行进一步的处理或展示
     *
     * @return 一个包含未使用钢管的列表，如果当前没有可用的钢管，则返回一个空列表
     */
    @Override
    public CommonResult<List<ZlSteelPipe>> unUsePipe() {
        List<ZlSteelPipe> list = zlSteelPipeMapper.unUsePipe();
        return CommonResult.success(list);
    }

    /**
     * 获取最近六个月的管道月统计信息
     * <p>
     * 本方法用于统计最近六个月（包括当前月）的管道相关数据
     * 它首先计算出五个月前的日期，并获取该月的第一天作为起始日期，
     * 然后获取当前月的最后一天作为结束日期接下来，调用Mapper层的方法
     * 获取在这段时间内的管道月统计信息，并将结果封装进CommonResult对象中返回
     *
     * @return 返回一个包含管道月统计信息列表的CommonResult对象
     */
    @Override
    public CommonResult<List<PipeMonthStatisticsVO>> monthsStatistics(Boolean fullMonth) {
        // 初始化起始日期为当前日期往前推五个月，并获取该月的第一天
        Calendar startDay = Calendar.getInstance();
        startDay.add(Calendar.MONTH, -5);
        Date startDate = DateUtils.getMonthStartDate(startDay.getTime());

        // 获取当前月的最后一天作为结束日期
        Date endDate = DateUtils.getMonthEndDate(new Date());

        // 调用Mapper层方法，获取指定日期范围内的管道月统计信息
        List<PipeMonthStatisticsVO> list = zlSteelPipeMapper.monthsStatistics(startDate, endDate);

        // 将统计信息列表封装进CommonResult对象并返回
        return CommonResult.success(this.buildMonthStatistics(list, fullMonth));
    }

    /**
     * 管节已完成数量和报废数量统计
     * 根据请求参数中的月份和钢管编号，统计钢管的状态信息
     * 如果指定了月份，则获取该月份的开始和结束日期，否则月份统计将不被执行
     *
     * @param reqVO 请求参数对象，包含可选的月份和钢管编号
     * @return 返回一个通用结果对象，包含统计结果
     */
    @Override
    public CommonResult<StatusStatisticsRespVO> statusStatistics(StatusReqVO reqVO) {
        // 获取月份的开始日期和结束日期，用于查询
        Date monthStartDate = reqVO.getMonth() != null ? DateUtils.getMonthStartDate(reqVO.getMonth()) : null;
        Date monthEndDate = reqVO.getMonth() != null ? DateUtils.getMonthEndDate(reqVO.getMonth()) : null;

        // 调用Mapper方法统计普通钢管和大口径钢管的状态信息
        StatusStatisticsRespVO pipe = zlSteelPipeMapper.statusStatistics(monthStartDate, monthEndDate, reqVO.getPipeNum());
        StatusStatisticsRespVO bigPipe = zlSteelBigPipeMapper.statusStatistics(monthStartDate, monthEndDate, reqVO.getPipeNum());

        // 初始化大口径钢管的报废和完成数量
        Integer bigScrapCount = bigPipe != null && bigPipe.getScrapCount() != null ? bigPipe.getScrapCount() : 0;
        Integer bigCompleteCount = bigPipe != null && bigPipe.getCompleteCount() != null ? bigPipe.getCompleteCount() : 0;

        // 确保pipe对象不为空，以便后续操作
        pipe = pipe == null ? new StatusStatisticsRespVO() : pipe;
        pipe.setScrapCount(pipe.getScrapCount() == null ? 0 : pipe.getScrapCount());
        pipe.setCompleteCount(0);

        // 更新pipe对象的报废和完成数量，包括了大口径钢管的数量
        pipe.setScrapCount(pipe.getScrapCount() + bigScrapCount);
        pipe.setCompleteCount(pipe.getCompleteCount() + bigCompleteCount);

        // 返回统计结果
        return CommonResult.success(pipe);
    }

    /**
     * 统计指定月份的钢管相关信息
     * 如果请求中未提供月份，则默认为当前月份
     * 该方法首先计算出指定月份的开始和结束时间，然后调用Mapper层方法进行统计数据的查询
     * 最后，根据查询结果和材料列表，匹配并生成最终的统计结果
     *
     * @param reqVO 统计请求对象，可能包含需要统计的月份
     * @return 返回包含统计结果的CommonResult对象
     */
    @Override
    public CommonResult<List<PipeStatisticsRespVO>> statistics(StatisticsReqVO reqVO) {
        // 初始化结果列表
        List<PipeStatisticsRespVO> result = new ArrayList<>();
        // 获取当前日期
        Date now = reqVO.getMonth() == null ? DateUtils.getNowDate() : reqVO.getMonth();
        // 计算当月的开始时间
        Date monthStartTime = DateUtils.getMonthStartDate(now);
        // 计算当月的结束时间
        Date monthEndTime = DateUtils.getMonthEndDate(now);
        // 调用mapper层方法，统计当月的钢板信息
        List<PipeStatisticsRespVO> list = zlSteelPipeMapper.statistics(monthStartTime, monthEndTime);
        // 遍历材料列表，匹配统计结果
        for (MaterialItem material : config.getMaterials()) {
            result.add(this.matchMaterial(list, material.getMaterial()));
        }
        // 返回统计结果
        return CommonResult.success(result);
    }


    /**
     * 根据大管节ID获取钢管道响应对象列表
     * 此方法首先根据大管节ID查询相关的钢管道实体，然后为每个实体创建一个响应对象，
     * 并复制属性，最后查询与每个管节相关的钢板列表并设置到响应对象中
     *
     * @param bigPipeId 大管节ID，用于查询相关的钢管道实体
     * @return SteelPipeRespVO对象列表，包含与大管节ID相关的所有钢管道信息
     */
    @Override
    public List<SteelPipeRespVO> listByPipeId(String bigPipeId) {
        // 初始化响应对象列表
        List<SteelPipeRespVO> respVOList = new ArrayList<>();
        // 查询大管节ID对应的钢管道实体列表
        List<ZlSteelPipe> list = zlSteelPipeMapper.selectByBigPipeId(bigPipeId);
        // 如果查询结果为空，直接返回空的响应列表
        if (CollectionUtils.isEmpty(list)) {
            return respVOList;
        }
        // 遍历查询到的钢管道实体
        for (ZlSteelPipe zlSteelPipe : list) {
            // 创建响应对象并复制属性
            SteelPipeRespVO respVO = new SteelPipeRespVO();
            BeanUtils.copyProperties(zlSteelPipe, respVO);
            // 查询并设置与该管节相关的钢板列表
            respVO.setSteelPlateList(zlSteelPlateMapper.listByPipeId(zlSteelPipe.getId()));
            // 将响应对象添加到列表中
            respVOList.add(respVO);
        }
        // 返回响应对象列表
        return respVOList;
    }


    /**
     * 根据ID验证并获取钢管信息
     * 此方法首先根据请求中的ID查询数据库中的钢管信息如果未找到对应的钢管信息，
     * 则抛出一个服务异常，提示未找到该管节信息如果找到了对应的钢管信息，则返回该信息
     *
     * @param id 请求中的钢管ID，用于查询特定的钢管信息
     * @return ZlSteelPipe 返回查询到的钢管信息对象，如果未找到，则抛出异常
     * @throws ServiceException 当未找到指定ID的钢管信息时抛出的服务异常
     */
    public ZlSteelPipe validate(String id) {
        // 根据请求中的ID查询钢管信息
        ZlSteelPipe zlSteelPipe = zlSteelPipeMapper.selectById(id);
        // 检查查询结果，如果为null，则返回错误信息
        if (zlSteelPipe == null) {
            throw new ServiceException(443, "未找到该管节信息");
        }
        // 返回查询到的钢管信息
        return zlSteelPipe;
    }

    /**
     * 构建最近六个月的统计信息列表
     *
     * @param list 原始的月统计信息列表
     * @return 最近六个月的统计信息列表
     */
    private List<PipeMonthStatisticsVO> buildMonthStatistics(List<PipeMonthStatisticsVO> list, Boolean fullMonth) {
        List<PipeMonthStatisticsVO> result = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat simpFormatter = new SimpleDateFormat("MM月");
        // 从当前月开始，向前推算包括当前月在内的最近六个月的统计信息
        for (int i = 5; i >= 0; i--) {
            // 设置为当前日期前 i 个月
            calendar.add(Calendar.MONTH, -i);
            Date monthStart = calendar.getTime();
            String month = formatter.format(monthStart);
            String simpMonth = null;
            if (!fullMonth) {
                simpMonth = simpFormatter.format(monthStart);
            }
            // 根据月份获取对应的统计信息
            result.add(this.matchStatistics(list, month, simpMonth));
            // 恢复到当前日期
            calendar.add(Calendar.MONTH, i);
        }
        return result;
    }

    /**
     * 根据月份查找统计信息
     *
     * @param list  统计信息列表
     * @param month 月份字符串，格式为"yyyy-MM"
     * @return 匹配月份的统计信息对象，如果没有找到，则返回管道数量为0的新对象
     */
    private PipeMonthStatisticsVO matchStatistics(List<PipeMonthStatisticsVO> list, String month, String simpMonthSrt) {
        if (CollectionUtils.isEmpty(list)) {
            PipeMonthStatisticsVO result = new PipeMonthStatisticsVO();
            result.setMonth(StringUtils.isNotBlank(simpMonthSrt) ? simpMonthSrt : month);
            result.setPipeCount(0);
            return result;
        }
        for (PipeMonthStatisticsVO pipe : list) {
            if (pipe.getMonth().equals(month)) {
                pipe.setMonth(StringUtils.isNotBlank(simpMonthSrt) ? simpMonthSrt : month);
                // 确保管道数量不为空，如果为空则设置为0
                pipe.setPipeCount(pipe.getPipeCount() == null ? 0 : pipe.getPipeCount());
                return pipe;
            }
        }
        // 如果没有找到匹配的统计信息，则返回一个新的统计信息对象，管道数量为0
        PipeMonthStatisticsVO result = new PipeMonthStatisticsVO();
        result.setMonth(StringUtils.isNotBlank(simpMonthSrt) ? simpMonthSrt : month);
        result.setPipeCount(0);
        return result;
    }

    /**
     * 根据材料名称匹配统计信息
     * 如果列表为空，创建并返回一个带有指定材料名称但总数和生产数量为0的新统计响应对象
     * 如果列表不为空，遍历列表寻找匹配指定材料名称的统计响应对象，初始化其生产数量和总数（如果未设置）
     * 如果未找到匹配项，创建并返回一个带有指定材料名称但总数和生产数量为0的新统计响应对象
     *
     * @param list     统计信息列表
     * @param material 材料名称
     * @return 匹配的统计响应对象，如果不存在则创建并返回一个新的统计响应对象
     */
    private PipeStatisticsRespVO matchMaterial(List<PipeStatisticsRespVO> list, String material) {
        // 检查列表是否为空
        if (CollectionUtils.isEmpty(list)) {
            // 创建一个新的统计响应对象，设置材料名称和默认的总数及生产数量
            PipeStatisticsRespVO me = new PipeStatisticsRespVO();
            me.setMaterial(material);
            me.setTotal(0);
            me.setProducedCount(0);
            return me;
        }
        // 遍历列表寻找匹配的材料名称
        for (PipeStatisticsRespVO item : list) {
            // 检查当前项的材料名称是否与指定的材料名称匹配
            if (material.equals(item.getMaterial())) {
                // 初始化生产数量和总数（如果未设置）
                item.setProducedCount(item.getProducedCount() == null ? 0 : item.getProducedCount());
                item.setTotal(item.getTotal() == null ? 0 : item.getTotal());
                return item;
            }
        }
        // 如果没有找到匹配项，创建一个新的统计响应对象，设置材料名称和默认的总数及生产数量
        PipeStatisticsRespVO me = new PipeStatisticsRespVO();
        me.setMaterial(material);
        me.setTotal(0);
        me.setProducedCount(0);
        return me;
    }


    /**
     * 获取管道完成情况的静态信息
     * <p>
     * 此方法通过调用mapper层的pipCompleteStatic方法来获取管道完成情况的静态信息，
     * 并将其封装在CommonResult对象中返回成功结果
     *
     * @return CommonResult<PipeCompleteVO> 返回一个包含管道完成情况静态信息的成功结果对象
     */
    @Override
    public CommonResult<PipeCompleteVO> pipCompleteStatic() {
        PipeCompleteVO pipeCompleteVO = zlSteelPipeMapper.pipCompleteStatic();
        return CommonResult.success(pipeCompleteVO);
    }


    /**
     * 月强度统计
     *
     * @return
     */
    @Override
    public CommonResult<List<PipeMonthStatisticsVO>> qdStatistics(boolean fullMonth) {
        List<PipeMonthStatisticsVO> result = new ArrayList<>(6);
        // 获取当前月的最后一天作为结束日期
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("MM月");
        SimpleDateFormat fullFormatter = new SimpleDateFormat("yyyy-MM");
        // 从当前月开始，向前推算包括当前月在内的最近六个月的统计信息
        for (int i = 5; i >= 0; i--) {
            // 设置为当前日期前 i 个月
            calendar.add(Calendar.MONTH, -i);
            Date monthStart = calendar.getTime();
            Date starDate = DateUtils.getMonthStartDate(monthStart);
            Date monthEnd = DateUtils.getMonthEndDate(monthStart);
            String month = formatter.format(monthStart);
            String fullMonthStr = fullFormatter.format(monthStart);
            Integer count = zlSteelPipeMapper.qdeStatistics(starDate, monthEnd);
            PipeMonthStatisticsVO stored = new PipeMonthStatisticsVO();
            stored.setPipeCount(count);
            stored.setMonth(fullMonth ? fullMonthStr : month);
            result.add(stored);
            // 恢复到当前日期
            calendar.add(Calendar.MONTH, i);
        }
        return CommonResult.success(result);
    }


    /**
     * 获取工艺信息概述
     * 该方法汇总了不同工艺阶段的数量信息，包括卷板工艺、纵缝焊接、环缝焊接和防腐处理的数量
     * 这些信息用于提供对当前生产状况的概览
     *
     * @return CommonResult<PipeProcedureInfo> 包含各种工艺数量信息的 PipeProcedureInfo 对象
     */
    @Override
    public CommonResult<PipeProcedureInfo> procedureInfo() {
        // 创建 PipeProcedureInfo 对象以存储各种工艺的数量信息
        PipeProcedureInfo info = new PipeProcedureInfo();

        //获取卷板工艺个数
        info.setCoilCount(zlSteelPipeMapper.countByProcedure(3));

        //纵缝焊接个数
        info.setWeldCount(zlSteelPipeMapper.countByProcedure(5));

        //环缝焊接个数
        info.setGirthWeldCount(zlSteelBigPipeMapper.countByProcedure(7));

        //防腐个数
        info.setAntisepsisCount(zlSteelBigPipeMapper.countByProcedure(12));

        //返回包含工艺信息的对象
        return CommonResult.success(info);
    }

}
